{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": 1,
   "id": "696b6de4-0773-424e-8b0a-66996f74f3c3",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Requirement already satisfied: openai in /Users/xiewentao/anaconda3/envs/deepseek/lib/python3.13/site-packages (1.84.0)\n",
      "Requirement already satisfied: requests in /Users/xiewentao/anaconda3/envs/deepseek/lib/python3.13/site-packages (2.32.3)\n",
      "Requirement already satisfied: tqdm in /Users/xiewentao/anaconda3/envs/deepseek/lib/python3.13/site-packages (4.67.1)\n",
      "Requirement already satisfied: torch in /Users/xiewentao/anaconda3/envs/deepseek/lib/python3.13/site-packages (2.7.1)\n",
      "Requirement already satisfied: pymilvus[model] in /Users/xiewentao/anaconda3/envs/deepseek/lib/python3.13/site-packages (2.5.10)\n",
      "Requirement already satisfied: setuptools>69 in /Users/xiewentao/anaconda3/envs/deepseek/lib/python3.13/site-packages (from pymilvus[model]) (78.1.1)\n",
      "Requirement already satisfied: grpcio<=1.67.1,>=1.49.1 in /Users/xiewentao/anaconda3/envs/deepseek/lib/python3.13/site-packages (from pymilvus[model]) (1.67.1)\n",
      "Requirement already satisfied: protobuf>=3.20.0 in /Users/xiewentao/anaconda3/envs/deepseek/lib/python3.13/site-packages (from pymilvus[model]) (6.31.1)\n",
      "Requirement already satisfied: python-dotenv<2.0.0,>=1.0.1 in /Users/xiewentao/anaconda3/envs/deepseek/lib/python3.13/site-packages (from pymilvus[model]) (1.1.0)\n",
      "Requirement already satisfied: ujson>=2.0.0 in /Users/xiewentao/anaconda3/envs/deepseek/lib/python3.13/site-packages (from pymilvus[model]) (5.10.0)\n",
      "Requirement already satisfied: pandas>=1.2.4 in /Users/xiewentao/anaconda3/envs/deepseek/lib/python3.13/site-packages (from pymilvus[model]) (2.3.0)\n",
      "Requirement already satisfied: milvus-lite>=2.4.0 in /Users/xiewentao/anaconda3/envs/deepseek/lib/python3.13/site-packages (from pymilvus[model]) (2.4.12)\n",
      "Requirement already satisfied: pymilvus.model>=0.3.0 in /Users/xiewentao/anaconda3/envs/deepseek/lib/python3.13/site-packages (from pymilvus[model]) (0.3.2)\n",
      "Requirement already satisfied: anyio<5,>=3.5.0 in /Users/xiewentao/anaconda3/envs/deepseek/lib/python3.13/site-packages (from openai) (4.9.0)\n",
      "Requirement already satisfied: distro<2,>=1.7.0 in /Users/xiewentao/anaconda3/envs/deepseek/lib/python3.13/site-packages (from openai) (1.9.0)\n",
      "Requirement already satisfied: httpx<1,>=0.23.0 in /Users/xiewentao/anaconda3/envs/deepseek/lib/python3.13/site-packages (from openai) (0.28.1)\n",
      "Requirement already satisfied: jiter<1,>=0.4.0 in /Users/xiewentao/anaconda3/envs/deepseek/lib/python3.13/site-packages (from openai) (0.10.0)\n",
      "Requirement already satisfied: pydantic<3,>=1.9.0 in /Users/xiewentao/anaconda3/envs/deepseek/lib/python3.13/site-packages (from openai) (2.11.5)\n",
      "Requirement already satisfied: sniffio in /Users/xiewentao/anaconda3/envs/deepseek/lib/python3.13/site-packages (from openai) (1.3.1)\n",
      "Requirement already satisfied: typing-extensions<5,>=4.11 in /Users/xiewentao/anaconda3/envs/deepseek/lib/python3.13/site-packages (from openai) (4.14.0)\n",
      "Requirement already satisfied: idna>=2.8 in /Users/xiewentao/anaconda3/envs/deepseek/lib/python3.13/site-packages (from anyio<5,>=3.5.0->openai) (3.10)\n",
      "Requirement already satisfied: certifi in /Users/xiewentao/anaconda3/envs/deepseek/lib/python3.13/site-packages (from httpx<1,>=0.23.0->openai) (2025.4.26)\n",
      "Requirement already satisfied: httpcore==1.* in /Users/xiewentao/anaconda3/envs/deepseek/lib/python3.13/site-packages (from httpx<1,>=0.23.0->openai) (1.0.9)\n",
      "Requirement already satisfied: h11>=0.16 in /Users/xiewentao/anaconda3/envs/deepseek/lib/python3.13/site-packages (from httpcore==1.*->httpx<1,>=0.23.0->openai) (0.16.0)\n",
      "Requirement already satisfied: annotated-types>=0.6.0 in /Users/xiewentao/anaconda3/envs/deepseek/lib/python3.13/site-packages (from pydantic<3,>=1.9.0->openai) (0.7.0)\n",
      "Requirement already satisfied: pydantic-core==2.33.2 in /Users/xiewentao/anaconda3/envs/deepseek/lib/python3.13/site-packages (from pydantic<3,>=1.9.0->openai) (2.33.2)\n",
      "Requirement already satisfied: typing-inspection>=0.4.0 in /Users/xiewentao/anaconda3/envs/deepseek/lib/python3.13/site-packages (from pydantic<3,>=1.9.0->openai) (0.4.1)\n",
      "Requirement already satisfied: charset_normalizer<4,>=2 in /Users/xiewentao/anaconda3/envs/deepseek/lib/python3.13/site-packages (from requests) (3.4.2)\n",
      "Requirement already satisfied: urllib3<3,>=1.21.1 in /Users/xiewentao/anaconda3/envs/deepseek/lib/python3.13/site-packages (from requests) (1.26.15)\n",
      "Requirement already satisfied: filelock in /Users/xiewentao/anaconda3/envs/deepseek/lib/python3.13/site-packages (from torch) (3.18.0)\n",
      "Requirement already satisfied: sympy>=1.13.3 in /Users/xiewentao/anaconda3/envs/deepseek/lib/python3.13/site-packages (from torch) (1.14.0)\n",
      "Requirement already satisfied: networkx in /Users/xiewentao/anaconda3/envs/deepseek/lib/python3.13/site-packages (from torch) (3.5)\n",
      "Requirement already satisfied: jinja2 in /Users/xiewentao/anaconda3/envs/deepseek/lib/python3.13/site-packages (from torch) (3.1.6)\n",
      "Requirement already satisfied: fsspec in /Users/xiewentao/anaconda3/envs/deepseek/lib/python3.13/site-packages (from torch) (2025.5.1)\n",
      "Requirement already satisfied: numpy>=1.26.0 in /Users/xiewentao/anaconda3/envs/deepseek/lib/python3.13/site-packages (from pandas>=1.2.4->pymilvus[model]) (2.3.0)\n",
      "Requirement already satisfied: python-dateutil>=2.8.2 in /Users/xiewentao/anaconda3/envs/deepseek/lib/python3.13/site-packages (from pandas>=1.2.4->pymilvus[model]) (2.9.0.post0)\n",
      "Requirement already satisfied: pytz>=2020.1 in /Users/xiewentao/anaconda3/envs/deepseek/lib/python3.13/site-packages (from pandas>=1.2.4->pymilvus[model]) (2025.2)\n",
      "Requirement already satisfied: tzdata>=2022.7 in /Users/xiewentao/anaconda3/envs/deepseek/lib/python3.13/site-packages (from pandas>=1.2.4->pymilvus[model]) (2025.2)\n",
      "Requirement already satisfied: transformers>=4.36.0 in /Users/xiewentao/anaconda3/envs/deepseek/lib/python3.13/site-packages (from pymilvus.model>=0.3.0->pymilvus[model]) (4.52.4)\n",
      "Requirement already satisfied: onnxruntime in /Users/xiewentao/anaconda3/envs/deepseek/lib/python3.13/site-packages (from pymilvus.model>=0.3.0->pymilvus[model]) (1.22.0)\n",
      "Requirement already satisfied: scipy>=1.10.0 in /Users/xiewentao/anaconda3/envs/deepseek/lib/python3.13/site-packages (from pymilvus.model>=0.3.0->pymilvus[model]) (1.15.3)\n",
      "Requirement already satisfied: six>=1.5 in /Users/xiewentao/anaconda3/envs/deepseek/lib/python3.13/site-packages (from python-dateutil>=2.8.2->pandas>=1.2.4->pymilvus[model]) (1.17.0)\n",
      "Requirement already satisfied: mpmath<1.4,>=1.1.0 in /Users/xiewentao/anaconda3/envs/deepseek/lib/python3.13/site-packages (from sympy>=1.13.3->torch) (1.3.0)\n",
      "Requirement already satisfied: huggingface-hub<1.0,>=0.30.0 in /Users/xiewentao/anaconda3/envs/deepseek/lib/python3.13/site-packages (from transformers>=4.36.0->pymilvus.model>=0.3.0->pymilvus[model]) (0.32.4)\n",
      "Requirement already satisfied: packaging>=20.0 in /Users/xiewentao/anaconda3/envs/deepseek/lib/python3.13/site-packages (from transformers>=4.36.0->pymilvus.model>=0.3.0->pymilvus[model]) (25.0)\n",
      "Requirement already satisfied: pyyaml>=5.1 in /Users/xiewentao/anaconda3/envs/deepseek/lib/python3.13/site-packages (from transformers>=4.36.0->pymilvus.model>=0.3.0->pymilvus[model]) (6.0.2)\n",
      "Requirement already satisfied: regex!=2019.12.17 in /Users/xiewentao/anaconda3/envs/deepseek/lib/python3.13/site-packages (from transformers>=4.36.0->pymilvus.model>=0.3.0->pymilvus[model]) (2024.11.6)\n",
      "Requirement already satisfied: tokenizers<0.22,>=0.21 in /Users/xiewentao/anaconda3/envs/deepseek/lib/python3.13/site-packages (from transformers>=4.36.0->pymilvus.model>=0.3.0->pymilvus[model]) (0.21.1)\n",
      "Requirement already satisfied: safetensors>=0.4.3 in /Users/xiewentao/anaconda3/envs/deepseek/lib/python3.13/site-packages (from transformers>=4.36.0->pymilvus.model>=0.3.0->pymilvus[model]) (0.5.3)\n",
      "Requirement already satisfied: hf-xet<2.0.0,>=1.1.2 in /Users/xiewentao/anaconda3/envs/deepseek/lib/python3.13/site-packages (from huggingface-hub<1.0,>=0.30.0->transformers>=4.36.0->pymilvus.model>=0.3.0->pymilvus[model]) (1.1.3)\n",
      "Requirement already satisfied: MarkupSafe>=2.0 in /Users/xiewentao/anaconda3/envs/deepseek/lib/python3.13/site-packages (from jinja2->torch) (3.0.2)\n",
      "Requirement already satisfied: coloredlogs in /Users/xiewentao/anaconda3/envs/deepseek/lib/python3.13/site-packages (from onnxruntime->pymilvus.model>=0.3.0->pymilvus[model]) (15.0.1)\n",
      "Requirement already satisfied: flatbuffers in /Users/xiewentao/anaconda3/envs/deepseek/lib/python3.13/site-packages (from onnxruntime->pymilvus.model>=0.3.0->pymilvus[model]) (25.2.10)\n",
      "Requirement already satisfied: humanfriendly>=9.1 in /Users/xiewentao/anaconda3/envs/deepseek/lib/python3.13/site-packages (from coloredlogs->onnxruntime->pymilvus.model>=0.3.0->pymilvus[model]) (10.0)\n"
     ]
    }
   ],
   "source": [
    "!pip install --upgrade \"pymilvus[model]\" openai requests tqdm torch"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "id": "cd6156a0-3cb5-4d1a-91be-ec91283f3554",
   "metadata": {},
   "outputs": [],
   "source": [
    "import os\n",
    "\n",
    "# 从环境变量获取 DeepSeek API Key\n",
    "api_key = os.getenv(\"DEEPSEEK_API_KEY\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "id": "88446a41-9f96-4c03-a942-fb0d4ce05ec3",
   "metadata": {},
   "outputs": [],
   "source": [
    "from glob import glob\n",
    "\n",
    "text_lines = []\n",
    "\n",
    "for file_path in glob(\"mfd.md\", recursive=True):\n",
    "    with open(file_path, \"r\") as file:\n",
    "        file_text = file.read()\n",
    "\n",
    "    text_lines += file_text.split(\"* \")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "id": "e147f485-f978-4724-b944-6fda94dd8103",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "388"
      ]
     },
     "execution_count": 6,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "len(text_lines)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "id": "1b6745c9-cf9f-452f-a92f-5fcf2b85c746",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "'本编调整因物的归属和利用产生的民事关系。\\n\\n**第二百零六条*'"
      ]
     },
     "execution_count": 7,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "text_lines[2]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "id": "a59a9ef0-f379-4168-bfb1-52b111629406",
   "metadata": {},
   "outputs": [],
   "source": [
    "from openai import OpenAI\n",
    "\n",
    "deepseek_client = OpenAI(\n",
    "    api_key=api_key,\n",
    "    base_url=\"https://api.deepseek.com/v1\",  # DeepSeek API 的基地址\n",
    ")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "id": "782d7d7a-8c29-48b7-96e2-b584179089d8",
   "metadata": {},
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "/Users/xiewentao/anaconda3/envs/deepseek/lib/python3.13/site-packages/tqdm/auto.py:21: TqdmWarning: IProgress not found. Please update jupyter and ipywidgets. See https://ipywidgets.readthedocs.io/en/stable/user_install.html\n",
      "  from .autonotebook import tqdm as notebook_tqdm\n"
     ]
    }
   ],
   "source": [
    "from pymilvus import model as milvus_model\n",
    "\n",
    "embedding_model = milvus_model.DefaultEmbeddingFunction()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "id": "94ac1e24-9da7-4da1-9771-4e08888ae237",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "768\n",
      "[-0.04836056  0.07163018 -0.01130064 -0.03789344 -0.03320646 -0.01318444\n",
      " -0.03041711 -0.02269505 -0.02317867 -0.00426023]\n"
     ]
    }
   ],
   "source": [
    "test_embedding = embedding_model.encode_queries([\"This is a test\"])[0]\n",
    "embedding_dim = len(test_embedding)\n",
    "print(embedding_dim)\n",
    "print(test_embedding[:10])"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "29b21820-3e1a-4836-a79d-aff997e5fcf2",
   "metadata": {},
   "source": [
    "## 将数据加载到 Milvus"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "3f3c7ae8-7528-4757-b2c1-c96808b4c52c",
   "metadata": {},
   "source": [
    "### 创建 Collection"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "id": "a152f5bc-ef8a-4751-94c7-da0d409c4221",
   "metadata": {},
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "huggingface/tokenizers: The current process just got forked, after parallelism has already been used. Disabling parallelism to avoid deadlocks...\n",
      "To disable this warning, you can either:\n",
      "\t- Avoid using `tokenizers` before the fork if possible\n",
      "\t- Explicitly set the environment variable TOKENIZERS_PARALLELISM=(true | false)\n"
     ]
    }
   ],
   "source": [
    "from pymilvus import MilvusClient\n",
    "\n",
    "milvus_client = MilvusClient(uri=\"./milvus_mfd.db\")\n",
    "\n",
    "collection_name = \"my_mfd_collection\""
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "id": "1db47613-ea5a-4f67-b8a3-54b2175d0adf",
   "metadata": {},
   "outputs": [],
   "source": [
    "if milvus_client.has_collection(collection_name):\n",
    "    milvus_client.drop_collection(collection_name)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "id": "1019a97e-9aba-4ab5-968b-89b72f7351a8",
   "metadata": {},
   "outputs": [],
   "source": [
    "milvus_client.create_collection(\n",
    "    collection_name=collection_name,\n",
    "    dimension=embedding_dim,\n",
    "    metric_type=\"IP\",  # 内积距离\n",
    "    consistency_level=\"Strong\",  # 支持的值为 (`\"Strong\"`, `\"Session\"`, `\"Bounded\"`, `\"Eventually\"`)。更多详情请参见 https://milvus.io/docs/consistency.md#Consistency-Level。\n",
    ")"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "4ad20dbe-54f1-4527-aeca-fbeeb68a3df2",
   "metadata": {},
   "source": [
    "### 插入数据"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 14,
   "id": "f0713273-7992-41cf-a135-c58be06cf7a9",
   "metadata": {},
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "huggingface/tokenizers: The current process just got forked, after parallelism has already been used. Disabling parallelism to avoid deadlocks...\n",
      "To disable this warning, you can either:\n",
      "\t- Avoid using `tokenizers` before the fork if possible\n",
      "Creating embeddings:   0%|                                                                                | 0/388 [00:00<?, ?it/s]TOKENIZERS_PARALLELISM=(true | false)\n",
      "Creating embeddings: 100%|██████████████████████████████████████████████████████████████████| 388/388 [00:00<00:00, 695168.71it/s]\n"
     ]
    },
    {
     "data": {
      "text/plain": [
       "{'insert_count': 388, 'ids': [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, 224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255, 256, 257, 258, 259, 260, 261, 262, 263, 264, 265, 266, 267, 268, 269, 270, 271, 272, 273, 274, 275, 276, 277, 278, 279, 280, 281, 282, 283, 284, 285, 286, 287, 288, 289, 290, 291, 292, 293, 294, 295, 296, 297, 298, 299, 300, 301, 302, 303, 304, 305, 306, 307, 308, 309, 310, 311, 312, 313, 314, 315, 316, 317, 318, 319, 320, 321, 322, 323, 324, 325, 326, 327, 328, 329, 330, 331, 332, 333, 334, 335, 336, 337, 338, 339, 340, 341, 342, 343, 344, 345, 346, 347, 348, 349, 350, 351, 352, 353, 354, 355, 356, 357, 358, 359, 360, 361, 362, 363, 364, 365, 366, 367, 368, 369, 370, 371, 372, 373, 374, 375, 376, 377, 378, 379, 380, 381, 382, 383, 384, 385, 386, 387], 'cost': 0}"
      ]
     },
     "execution_count": 14,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "from tqdm import tqdm\n",
    "\n",
    "data = []\n",
    "\n",
    "doc_embeddings = embedding_model.encode_documents(text_lines)\n",
    "\n",
    "for i, line in enumerate(tqdm(text_lines, desc=\"Creating embeddings\")):\n",
    "    data.append({\"id\": i, \"vector\": doc_embeddings[i], \"text\": line})\n",
    "\n",
    "milvus_client.insert(collection_name=collection_name, data=data)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "7ee45863-1208-4a65-82f5-62e9a0d938a4",
   "metadata": {},
   "source": [
    "## 构建 RAG"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "48fa2d35-89e5-46e7-96ad-e5f1a98f77c2",
   "metadata": {},
   "source": [
    "### 检索查询数据"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 15,
   "id": "f8a84366-c305-4973-90fc-debb0b4ed227",
   "metadata": {},
   "outputs": [],
   "source": [
    "question = \"居住权可以转让或继承吗？\""
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 16,
   "id": "f02f8c9f-c409-49fa-bffe-f5477d4b9ab1",
   "metadata": {},
   "outputs": [],
   "source": [
    "search_res = milvus_client.search(\n",
    "    collection_name=collection_name,\n",
    "    data=embedding_model.encode_queries(\n",
    "        [question]\n",
    "    ),  # 将问题转换为嵌入向量\n",
    "    limit=3,  # 返回前3个结果\n",
    "    search_params={\"metric_type\": \"IP\", \"params\": {}},  # 内积距离\n",
    "    output_fields=[\"text\"],  # 返回 text 字段\n",
    ")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 18,
   "id": "f98ee6a1-93cc-44c6-920f-60f2cfcb361a",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[\n",
      "    [\n",
      "        \"土地承包经营权人依法对承包地享有占有、使用、收益的权利。\\n土地承包经营权人可以采取出租、入股或者其他方式流转土地经营权。\\n\\n**第三百六十一条*\",\n",
      "        0.696639895439148\n",
      "    ],\n",
      "    [\n",
      "        \"共同共有人对共有的不动产或者动产共同享有所有权。\\n共同共有人对共有财产享有平等的占有、使用、收益和处分的权利。\\n\\n**第三百一十三条*\",\n",
      "        0.696639895439148\n",
      "    ],\n",
      "    [\n",
      "        \"业主应当遵守法律、法规以及管理规约。\\n管理规约对全体业主具有约束力。\\n\\n**第二百八十五条*\",\n",
      "        0.696639895439148\n",
      "    ]\n",
      "]\n"
     ]
    }
   ],
   "source": [
    "import json\n",
    "\n",
    "retrieved_lines_with_distances = [\n",
    "    (res[\"entity\"][\"text\"], res[\"distance\"]) for res in search_res[0]\n",
    "]\n",
    "print(json.dumps(retrieved_lines_with_distances, indent=4, ensure_ascii=False))"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "7df3b7f7-dce4-43ec-8927-bccd96bee381",
   "metadata": {},
   "source": [
    "### 使用 LLM 获取 RAG 响应"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 19,
   "id": "ddd772d7-367e-4399-b91b-07f0d89c57d3",
   "metadata": {},
   "outputs": [],
   "source": [
    "context = \"\\n\".join(\n",
    "    [line_with_distance[0] for line_with_distance in retrieved_lines_with_distances]\n",
    ")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 20,
   "id": "950f28de-fb8d-42e4-9f86-f67eea035613",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "'土地承包经营权人依法对承包地享有占有、使用、收益的权利。\\n土地承包经营权人可以采取出租、入股或者其他方式流转土地经营权。\\n\\n**第三百六十一条*\\n共同共有人对共有的不动产或者动产共同享有所有权。\\n共同共有人对共有财产享有平等的占有、使用、收益和处分的权利。\\n\\n**第三百一十三条*\\n业主应当遵守法律、法规以及管理规约。\\n管理规约对全体业主具有约束力。\\n\\n**第二百八十五条*'"
      ]
     },
     "execution_count": 20,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "context"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 21,
   "id": "fe0c5ab7-025b-460d-81c4-a6fba8695b91",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "'居住权可以转让或继承吗？'"
      ]
     },
     "execution_count": 21,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "question"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 24,
   "id": "a4ccd97e-4828-4f7a-a1df-cf8251bac924",
   "metadata": {},
   "outputs": [],
   "source": [
    "SYSTEM_PROMPT = \"\"\"\n",
    "Human: 你是一个 AI 助手。你能够从提供的上下文段落片段中找到问题的答案。\n",
    "\"\"\"\n",
    "USER_PROMPT = f\"\"\"\n",
    "请使用以下用 <context> 标签括起来的信息片段来回答用 <question> 标签括起来的问题。\n",
    "<context>\n",
    "{context}\n",
    "</context>\n",
    "<question>\n",
    "{question}\n",
    "</question>\n",
    "\"\"\""
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 25,
   "id": "b923fd8f-fcfd-4e56-9b0b-7696abb76fd2",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "'\\n请使用以下用 <context> 标签括起来的信息片段来回答用 <question> 标签括起来的问题。\\n<context>\\n土地承包经营权人依法对承包地享有占有、使用、收益的权利。\\n土地承包经营权人可以采取出租、入股或者其他方式流转土地经营权。\\n\\n**第三百六十一条*\\n共同共有人对共有的不动产或者动产共同享有所有权。\\n共同共有人对共有财产享有平等的占有、使用、收益和处分的权利。\\n\\n**第三百一十三条*\\n业主应当遵守法律、法规以及管理规约。\\n管理规约对全体业主具有约束力。\\n\\n**第二百八十五条*\\n</context>\\n<question>\\n居住权可以转让或继承吗？\\n</question>\\n'"
      ]
     },
     "execution_count": 25,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "USER_PROMPT"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 26,
   "id": "5bd36d85-ddb6-4e56-bfa4-eb9a5dcc36b0",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "根据提供的上下文信息，并未明确提及“居住权”是否可以转让或继承的相关法律规定。上下文主要涉及的是土地承包经营权、共同共有财产权以及业主的管理规约等内容，因此无法从中得出关于居住权转让或继承的直接答案。\n",
      "\n",
      "若需准确回答该问题，建议参考《中华人民共和国民法典》中关于“居住权”的具体条款（如第十四章第366条至第371条），其中明确规定居住权原则上不得转让或继承（除非另有约定）。当前提供的法律条文片段未涵盖相关内容。\n"
     ]
    }
   ],
   "source": [
    "response = deepseek_client.chat.completions.create(\n",
    "    model=\"deepseek-chat\",\n",
    "    messages=[\n",
    "        {\"role\": \"system\", \"content\": SYSTEM_PROMPT},\n",
    "        {\"role\": \"user\", \"content\": USER_PROMPT},\n",
    "    ],\n",
    ")\n",
    "print(response.choices[0].message.content)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "be4e49cf-6de1-4d1d-91d4-da10294a33b2",
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3 (ipykernel)",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.13.4"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
